<script lang="ts" setup>
import { MenuTypeConst } from '@/constant';
import type { SaveMenuVo } from '@/openapi-generator';
import { useMenuStore } from '@/stores/menu';
import type { SysMenuEx } from '@/types/sys-menu-tree';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { message, Modal, type FormInstance } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import type { ColumnsType } from 'ant-design-vue/es/table/interface';
import type { DefaultOptionType } from 'ant-design-vue/lib/vc-tree-select/TreeSelect';
import { createVNode, onMounted, reactive, ref } from 'vue';

// javascript
const menuStore = useMenuStore();
const formRef = ref<FormInstance>();
const state = reactive({
  loading: false,
  visible: false,
  confirmLoading: false,
  iconSelectVisible: false
});
const page = reactive({
  current: 1,
  size: 10,
  total: 0
});
const table = reactive({
  loading: false,
  columns: ([
    // { title: "序号", dataIndex: "index", align: 'center', width: 120 },
    { title: "菜单名称", dataIndex: "name" },
    { title: "图标", dataIndex: "icon", align: "center" },
    { title: "前端路由", dataIndex: "frontEndRouter" },
    { title: "组件路径", dataIndex: "componentPath" },
    { title: "显示状态", dataIndex: "showStatus", align: "center" },
    { title: "菜单类型", dataIndex: "menuType", align: "center" },
    { title: "排序", dataIndex: "sort", align: "center" },
    { title: "状态", dataIndex: "enable", width: 100, align: "center" },
    { title: "创建时间", dataIndex: "createTime" },
    { title: "操作", dataIndex: "operation", width: 120 }
  ] as ColumnsType),
  data: menuStore.menu.value as SysMenuEx[]
});
const formMenuOptions = ref<DefaultOptionType[]>([]);
const form = ref<SaveMenuVo>({
  id: 0,
  name: "",
  sort: 0,
  parentId: null as any,
  icon: "",
  menuType: MenuTypeConst.Menu.value as number,
  showStatus: true,
  frontEndRouter: "",
  componentPath: "",
  permission: "",
  enable: true
});
const rules = reactive<Record<string, Rule[]>>({
  name: [{ required: true, message: '请输入菜单名称!' }],
  frontEndRouter: [
    {
      validator: (rule: Rule, value: string) => {
        if (form.value.menuType !== MenuTypeConst.Button.value && !value.trim()) {
          return Promise.reject("请输入前端路由地址");
        }
        return Promise.resolve();
      }
    }
  ],
  componentPath: [
    {
      validator: (rule: Rule, value: string) => {
        if (form.value.menuType === MenuTypeConst.Menu.value && !value.trim()) {
          return Promise.reject("请输入前端组件路径");
        }
        return Promise.resolve();
      }
    }
  ],
  permission: [
    {
      validator: (rule: Rule, value: string) => {
        if (form.value.menuType !== MenuTypeConst.Directory.value && !value.trim()) {
          return Promise.reject("请输入权限标识");
        }
        return Promise.resolve();
      }
    }
  ]
});

// 搜索、条件变化
const onSearch = () => {
  page.current = 1;
  loadMenuList();
}

// 分页事件
const onPageChange = () => {
  console.log(page.current);
  loadMenuList();
}

// 加载菜单列表
const loadMenuList = async () => {
  await menuStore.reloadMenu();
  table.data = menuStore.menu.value;
  formMenuOptions.value = getMenuOption(menuStore.menu.value);
}

// 设置菜单选项
const getMenuOption = (data: SysMenuEx[]) => {
  const options: DefaultOptionType[] = data.map(x => {
    return {
      title: x.name,
      value: x.id,
      children: x.children && x.children.length ? getMenuOption(x.children) : []
    }
  });
  return options;
}

// 图标选择器选择事件
const onIconSelected = (className: string) => {
  form.value.icon = className;
}

// 打开提交表单
const onShowFormDialog = (record?: SysMenuEx) => {
  form.value = {
    id: record?.id || 0,
    name: record?.name || "",
    sort: record?.sort || 0,
    parentId: (record?.parentId || null) as any,
    icon: record?.icon || "",
    menuType: record?.menuType || MenuTypeConst.Menu.value as number,
    showStatus: record?.showStatus || true,
    frontEndRouter: record?.frontEndRouter || "",
    componentPath: record?.componentPath || "",
    permission: record?.permission || "",
    enable: record?.enable || true
  }
  state.visible = true;
}

// 确认提交表单
const onConfirmSubmitForm = async () => {
  try {
    formRef.value && await formRef.value.validate();
  } catch (error) {
    return
  }
  submitForm();
}

// 数据校验成功提交表单
const submitForm = async () => {
  let res;
  try {
    state.confirmLoading = true;
    res = await $adminApi.sysMenuSave(form.value);
  } catch (error) {
    return
  } finally {
    state.confirmLoading = false;
  }
  form.value.id = res.data;
  state.visible = false;
  message.success("操作成功");
  loadMenuList();
  // 更新路由
  // menuStore.updateRouterRecord({
  //   parentId: form.value.parentId,
  //   frontEndRouter: form.value.frontEndRouter,
  //   path: form.value.componentPath,
  //   meta: { title: form.value.name }
  // });
}

// 删除菜单
const onDeleteMenu = (record: SysMenuEx) => {
  Modal.confirm({
    title: '确认删除这条数据吗？',
    icon: createVNode(ExclamationCircleOutlined),
    content: "删除后无法恢复，请确认！",
    centered: true,
    onOk: async () => {
      try {
        await $adminApi.sysMenuDeleteById(record.id);
      } catch (error) {
        return Promise.reject();
      }
      loadMenuList();
    }
  });
}

onMounted(() => {
  formMenuOptions.value = getMenuOption(menuStore.menu.value);
});
</script>
<script lang="ts">
export default { name: "menuManage" }
</script>

<!-- template -->
<template>
  <section class="container">
    <table-layout :show-page="false" :show-filter="false" v-model:current="page.current" :total="page.total" @search="onSearch" @page-change="onPageChange">

      <!-- 表格头部按钮部分 -->
      <template #table-header-btn>
        <a-button type="primary" @click="onShowFormDialog()">+ 添加</a-button>
      </template>

      <!-- 自定义渲染表格部分 -->
      <template #table-content>
        <a-table :loading="state.loading" bordered row-key="id" :pagination="false" :columns="table.columns"
          :data-source="table.data" :size="$config.TABLE_SIZE">
          <template #bodyCell="{ column, record }">

            <!-- 图标 -->
            <template v-if="column.dataIndex == 'icon'">
              <span class="icon" :class="record.icon"></span>
            </template>

            <!-- 显示状态 -->
            <template v-if="column.dataIndex == 'showStatus'">
              <a-tag color="processing" v-if="record.showStatus">显示</a-tag>
              <a-tag color="error" v-else>隐藏</a-tag>
            </template>

            <!-- 菜单类型 -->
            <template v-if="column.dataIndex == 'menuType'">
              <span>{{ MenuTypeConst.toLabel(record.menuType) }}</span>
            </template>

            <!-- 启用状态 -->
            <template v-if="column.dataIndex == 'enable'">
              <a-switch v-model:checked="record.enable" checked-children="启用" un-checked-children="停用" />
            </template>

            <template v-else-if="column.dataIndex == 'operation'">
              <a-button danger type="link" @click="onDeleteMenu(record)">删除</a-button>
              <a-divider type="vertical" />
              <a-button type="link" @click="onShowFormDialog(record)">编辑</a-button>
            </template>
          </template>
        </a-table>
      </template>
    </table-layout>
  </section>

  <a-modal @ok="onConfirmSubmitForm" :confirm-loading="state.confirmLoading" centered v-model:visible="state.visible"
    title="编辑菜单">
    <div class="modal-body">
      <a-form ref="formRef" :rules="rules" :model="form" :label-col="{ span: 5 }">
        <a-form-item label="菜单名称" name="name">
          <a-input v-model:value="form.name" />
        </a-form-item>

        <a-form-item label="上级菜单" name="parentId">
          <a-tree-select placeholder="根目录" v-model:value="form.parentId" :tree-line="{ showLeafIcon: false }"
            :tree-data="formMenuOptions" />
        </a-form-item>

        <a-form-item label="菜单类型" name="menuType">
          <a-radio-group v-model:value="form.menuType" :options="MenuTypeConst.list()" />
        </a-form-item>

        <a-form-item label="是否显示" name="showStatus">
          <a-switch v-model:checked="form.showStatus" />
        </a-form-item>

        <a-form-item label="图标" name="icon">
          <p @click="state.iconSelectVisible = true">
            <a-input class="icon-input" readonly v-model:value="form.icon">
              <template v-if="form.icon" #addonAfter>
                <span :class="form.icon"></span>
              </template>
            </a-input>
          </p>
        </a-form-item>

        <a-form-item label="排序" name="sort">
          <a-input-number v-model:value="form.sort" :min="0" />
        </a-form-item>

        <a-form-item label="路由地址" name="frontEndRouter" v-if="form.menuType != MenuTypeConst.Button.value">
          <a-input v-model:value="form.frontEndRouter" />
        </a-form-item>

        <a-form-item label="组件路径" name="componentPath" v-if="form.menuType == MenuTypeConst.Menu.value">
          <a-input v-model:value="form.componentPath" />
        </a-form-item>

        <a-form-item label="权限标识" name="permission" v-if="form.menuType != MenuTypeConst.Directory.value">
          <a-input v-model:value="form.permission" />
        </a-form-item>
      </a-form>
    </div>
  </a-modal>

  <fontawesome-icon-select @selected="onIconSelected" v-model:visible="state.iconSelectVisible" />
</template>

<style lang="less" scoped>
// less
.container {
  height: 100%;
}

.modal-body {
  .icon-input {
    cursor: pointer;
  }
}
</style>